package utiltool

import (
	"context"
	"gitee.com/dennis-kk/rpc-go-backend/idlrpc"
	idlcommon "gitee.com/dennis-kk/rpc-go-backend/idlrpc/common"
	"gitee.com/dennis-kk/rpc-go-backend/idlrpc/net"
	"gitee.com/dennis-kk/rpc-go-backend/idlrpc/transport"
)

var (
	listeners map[uint64]*MockAccept
	connecter map[uint64]*MockConnect
)

type MockConnect struct {
	connId uint64              //网络层赋值，不同网络库不同实现
	trans  transport.Transport //trans指针
}

type MockAccept struct {
	connId  uint64
	connMap map[uint64]*MockConnect
}

func NewMockAccept() *MockAccept {
	return &MockAccept{
		connId:  idlcommon.GetConnID(),
		connMap: make(map[uint64]*MockConnect),
	}
}

func NewMockConnector() *MockConnect {
	return &MockConnect{}
}

// 服务器监听 成功回调函数
func (accept *MockAccept) OnAccept(conn net.IdlConn) bool {
	if conn == nil {
		return false
	}

	trans := NewMockTrans(conn)
	if trans == nil {
		return false
	}

	rc := &MockConnect{
		connId: conn.GetConnID(),
		trans:  trans,
	}
	conn.SetHandle(rc)
	accept.connMap[rc.connId] = rc
	connecter[rc.connId] = rc
	return true
}

//客户端主动连接成功 可以开始跑测试了
func (connect *MockConnect) OnConnect(conn net.IdlConn) bool {
	//检查connid 的是否重复，理论上要关闭旧的 替换新的
	trans := NewMockTrans(conn)
	if trans == nil {
		return false
	}
	connect.connId = conn.GetConnID()
	connect.trans = trans
	conn.SetHandle(connect)
	//启动测试
	connecter[connect.connId] = connect
	return true
}

// 这个在网路线程里面所以调度会特别麻烦，应该是在主线程里面调用才行
// 已经修改为主线程调用了
func (connect *MockConnect) OnRecv(pkg []byte) bool {
	//拷贝一份 这里要发拷贝的 slice, 不然网络协程里重新接收会把数据写坏
	connect.trans.Wirte(pkg, len(pkg))
	idlrpc.OnMessage(connect.trans, context.Background())
	return true
}

//关闭完成调用这个函数
func (connect *MockConnect) OnClose() {
	if connect == nil {
		return
	}
	if connect.trans == nil {
		return
	}
	connect.trans.Close()
	delete(connecter, connect.connId)
}
